package com.pdg.mcplugin.tsa;

import java.util.logging.Logger;

import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.Sign;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockListener;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.permissions.Permission;

public class TSABlockListener extends BlockListener {

	//plugin
	private TSA plugin;
	public TSA getPlugin(){
		return plugin;
	}
	
	//constructor
	public TSABlockListener(TSA thePlugin){
		plugin = thePlugin;
	}
	
	//logger - from plugin
	public Logger getLogger(){
		return getPlugin().getLogger();
	}
	
	//grab departure destroy
	private boolean hasDepartureDestroy(Player player){
		//create permission if it doesn't exist
		if(getPlugin().getPluginManager().getPermission(Constants.permissionDepatureSignDestroy)==null){
			getPlugin().getPluginManager().addPermission(new Permission(Constants.permissionDepatureSignDestroy, Constants.permissionDefaultDepatureSignDestroy));
		}
		return player.hasPermission(Constants.permissionDepatureSignDestroy);
	}

	//grab arrival destroy
	private boolean hasArrivalDestroy(Player player){
		//create permission if it doesn't exist
		if(getPlugin().getPluginManager().getPermission(Constants.permissionArrivalSignDestroy)==null){
			getPlugin().getPluginManager().addPermission(new Permission(Constants.permissionArrivalSignDestroy, Constants.permissionDefaultArrivalSignDestroy));
		}
		return player.hasPermission(Constants.permissionArrivalSignDestroy);
	}
	
	//breaking blocks
	public void onBlockBreak(BlockBreakEvent event){
		Block theBlock = event.getBlock();
		if(theBlock.getType()==Material.DOUBLE_STEP){
			if(getPlugin().getDataProvider().getBlockProtection(event.getBlock().getLocation())>Constants.protectionZero){
				event.getPlayer().sendMessage(Constants.errorBlockProtectedByTSA);
				event.setCancelled(true);
			}
		}else if(theBlock.getType()==Material.WALL_SIGN || theBlock.getType()==Material.SIGN_POST){
			if(theBlock.getState() instanceof Sign){
				Sign theSign = (Sign)theBlock.getState();
				if(theSign.getLine(Constants.signLineTsa).equalsIgnoreCase(Constants.signStartLine)){
					org.bukkit.material.Sign signData = (org.bukkit.material.Sign)theBlock.getState().getData();
					Block theNextBlock = theBlock.getRelative(signData.getAttachedFace());
					if(theSign.getLine(Constants.signLineType).equalsIgnoreCase(Constants.signArrivalLine)){
						if(hasArrivalDestroy(event.getPlayer())){
							event.getPlayer().sendMessage(Constants.messageArrivalPointDestroyed);
							getPlugin().getDataProvider().decrementBlockProtection(theNextBlock.getLocation());
							getPlugin().getDataProvider().deleteArrival(theSign.getLine(Constants.signLineArrivalPoint));
						}else{
							event.getPlayer().sendMessage(Constants.errorNoPermissionToDestroyArrivalSign);
							event.setCancelled(true);
						}
					}else if(theSign.getLine(Constants.signLineType).equalsIgnoreCase(Constants.signDepartureLine)){
						if(hasDepartureDestroy(event.getPlayer())){
							event.getPlayer().sendMessage(Constants.messageDeparturePointDestroyed);
							getPlugin().getDataProvider().decrementBlockProtection(theNextBlock.getLocation());
						}else{
							event.getPlayer().sendMessage(Constants.errorNoPermissionToDestroyDepartureSign);
							event.setCancelled(true);
						}
					}
				}
			}
		}
	}
	
	//checking for permission to place arrival signs
	private boolean hasArrivalPlacePermission(Player player){
		//create permission if it doesn't already exist
		if(getPlugin().getPluginManager().getPermission(Constants.permissionArrivalSignCreate)==null){
			getPlugin().getPluginManager().addPermission(new Permission(Constants.permissionArrivalSignCreate, Constants.permissionDefaultArrivalSignCreate));
		}
		return player.hasPermission(Constants.permissionArrivalSignCreate);
	}
	
	//checking for permission to replace arrival signs
	private boolean hasArrivalReplacePermission(Player player){
		//create permission if it doesn't already exist
		if(getPlugin().getPluginManager().getPermission(Constants.permissionArrivalSignUpdate)==null){
			getPlugin().getPluginManager().addPermission(new Permission(Constants.permissionArrivalSignUpdate, Constants.permissionDefaultArrivalSignUpdate));
		}
		return player.hasPermission(Constants.permissionArrivalSignUpdate);
	}
	
	//checking for permission to place departure signs
	private boolean hasDeparturePlacePermission(Player player){
		//create permission if it doesn't already exist
		if(getPlugin().getPluginManager().getPermission(Constants.permissionDepartureSignCreate)==null){
			getPlugin().getPluginManager().addPermission(new Permission(Constants.permissionDepartureSignCreate, Constants.permissionDefaultDepartureSignCreate));
		}
		return player.hasPermission(Constants.permissionDepartureSignCreate);
	}
	
	public void onSignChange(SignChangeEvent event){
		//grab lines of the sign
		String[] lines = event.getLines();
		
		//first line must be [TSA]
		if(lines[Constants.signLineTsa].equalsIgnoreCase(Constants.signStartLine)){
			
			Block theBlock = event.getBlock();
			org.bukkit.material.Sign signData = (org.bukkit.material.Sign)theBlock.getState().getData();
			Block theNextBlock = theBlock.getRelative(signData.getAttachedFace());
			if(theNextBlock.getType()!=Material.DOUBLE_STEP){
				event.getPlayer().sendMessage(Constants.errorMustPlaceOnDoubleStep);
				event.setCancelled(true);
				return;
			}
			
			
			//is this an arrival point?
			if(lines[Constants.signLineType].equalsIgnoreCase(Constants.signArrivalLine)){
				
				//check player permissions
				if(!hasArrivalPlacePermission(event.getPlayer())){
					
					//not allowed!
					event.getPlayer().sendMessage(Constants.errorNoPermissionToPlaceArrivalPoint);
					event.setCancelled(true);
					return;
				}
				
				//check for a non-null arrival point
				if(!lines[Constants.signLineArrivalPoint].isEmpty()){
					if(getPlugin().getDataProvider().retrieveArrival(lines[Constants.signLineArrivalPoint])==null){
						if(getPlugin().getDataProvider().createArrival(lines[Constants.signLineArrivalPoint],event.getPlayer().getLocation())){
							event.getPlayer().sendMessage(Constants.messageArrivalPointCreated);
							getPlugin().getDataProvider().incrementBlockProtection(theNextBlock.getLocation());
							return;
						}else{
							event.getPlayer().sendMessage(Constants.errorCouldNotCreateArrivalSign);
							event.setCancelled(true);
							return;
						}
					}else{
						if(hasArrivalReplacePermission(event.getPlayer())){
							getPlugin().getDataProvider().deleteArrival(lines[Constants.signLineArrivalPoint]);
							if(getPlugin().getDataProvider().createArrival(lines[Constants.signLineArrivalPoint],event.getPlayer().getLocation())){
								event.getPlayer().sendMessage(Constants.messageArrivalPointReplaced);
								getPlugin().getDataProvider().incrementBlockProtection(theNextBlock.getLocation());
								return;
							}else{
								event.getPlayer().sendMessage(Constants.errorCouldNotReplaceArrivalSign);
								event.setCancelled(true);
								return;
							}
						}else{
							event.getPlayer().sendMessage(Constants.errorNoPermissionToReplaceArrivalPoint);
							event.setCancelled(true);
							return;
						}
					}
				}else{//null arrival point
					event.getPlayer().sendMessage(Constants.errorInvalidArrivalPoint);
					event.setCancelled(true);
					return;
				}
				
			}else if(lines[Constants.signLineType].equalsIgnoreCase(Constants.signDepartureLine)){//or a departure point?
				
				//check permission
				if(!hasDeparturePlacePermission(event.getPlayer())){
					//no permission
					event.getPlayer().sendMessage(Constants.errorNoPermissionToPlaceDeparturePoint);
					event.setCancelled(true);
					return;
				}
				//check for a valid arrival point
				if(!lines[Constants.signLineArrivalPoint].isEmpty()){
					try{
						//check for a valid cost
						if(!lines[Constants.signLineCost].isEmpty()){
							Double cost = Double.valueOf(lines[Constants.signLineCost]);
							
							//check for non-negative cost
							if(cost>=Constants.costZero){
								event.getPlayer().sendMessage(Constants.messageDeparturePointCreated);
								getPlugin().getDataProvider().incrementBlockProtection(theNextBlock.getLocation());
								return;
							}else{
								//negative cost specified
								event.getPlayer().sendMessage(Constants.errorNegativeTravelCost);
								event.setCancelled(true);
								return;
							}
						}else{
							//invalid cost
							event.getPlayer().sendMessage(Constants.errorCostNotSpecified);
							event.setCancelled(true);
							return;
						}
					}catch(Exception e){
						event.getPlayer().sendMessage(Constants.errorInvalidCost);
						event.setCancelled(true);
						return;
					}
				}else{
					event.getPlayer().sendMessage(Constants.errorNoArrivalPointSpecified);
					event.setCancelled(true);
					return;
				}
			}else{//not arrival or departure... so not a valid TSA sign
				event.getPlayer().sendMessage(Constants.errorInvalidSignType);
				event.setCancelled(true);
				return;
			}
		}
	}
}
